/*
 * @FileName: loop.h
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-07-12 16:05:59
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-14 11:10:42
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#ifndef __LOOP_H__
#define __LOOP_H__

#include "bsp.h"
#include "easy_pid_f32.h"
#include "easy_filter.h"
#include "bsp_pwm.h"
#include "dev_info.h"
#include "app_mppt.h"
#include "app_analog.h"


typedef enum {
    MUX_NONE = 0, // 无环路竞争成功，所有环路饱和
    MUX_VLOOP,
    MUX_ILOOP,
    MUX_GLOOP
} mux_t;


extern easy_pid_f32_t pid_pv1_vin;
extern easy_pid_f32_t pid_pv1_iin;
extern easy_pid_f32_t pid_pv1_vout;
extern uint16_t loop_en;
extern float iref_test;

static inline float loop_pv1_run(float vin, float iin, float vout)
{
    float iref, duty1, duty2;
//    iref = easy_pid_run(&pid_pv1_vin, pid_pv1_vin.ref - vin);
    iref = easy_pid_run(&pid_pv1_vin, 10.0f - vin);
    easy_pid_set_ref(&pid_pv1_iin, iref);
    if (vin < 10) vin = 10;
//    duty1 = easy_pid_run(&pid_pv1_iin, pid_pv1_iin.ref - iin) / vin;
    duty1 = easy_pid_run(&pid_pv1_iin, pid_pv1_iin.ref - iin) / 50;
    duty2 = easy_pid_run(&pid_pv1_vout, pid_pv1_vout.ref - vout) / 50;

    if (duty1 > duty2) {
        duty1 = duty2;
    }
    return duty1;
}

static inline void loop_clear(easy_pid_f32_t * obj)
{
    easy_pid_clear_f32(obj);
}

static inline void loop_setRef(easy_pid_f32_t * obj, float ref)
{
    easy_pid_set_ref(obj, ref);
}

static inline void loop_enable(void)
{
    loop_en = true;
}

static inline void loop_disable(void)
{
    loop_en = false;
}

static inline uint16_t loop_getEn(void)
{
    return loop_en;
}

void loop_init(void);

#endif // __LOOP_H__

